#include <stdio.h>
#include<stdlib.h>
#include<time.h>
#include<WINSOCK2.h>
#include<string.h>
#include<iostream>
#include<tchar.h>
#include "windows.h"
#pragma comment(lib,"WS2_32.lib")
#define BUF_SIZE 64
#define baud 9600
#define comx "COM3"
//设置头文件，库文件与常量（缓冲区大小）

//串口
HANDLE hCom; //全局变量，串口句柄

int serial_open(LPCWSTR COMx, int BaudRate) {

	hCom = CreateFile(COMx, //COM1口    
		GENERIC_READ | GENERIC_WRITE, //允许读和写    
		0, //独占方式    
		NULL,
		OPEN_EXISTING, //打开而不是创建     
		0, //重叠方式FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED  (同步方式设置为0)
		NULL);
	if (hCom == INVALID_HANDLE_VALUE)
	{
		printf("打开COM失败!\n");
		return FALSE;
	}
	else
		printf("打开COM成功!\n");
	SetupComm(hCom, 1024, 1024); //输入缓冲区和输出缓冲区的大小都是1024 

	DCB dcb;
	GetCommState(hCom, &dcb);
	dcb.BaudRate = BaudRate;		//设置波特率为BaudRate
	dcb.ByteSize = 4;					//每个字节有8位 
	dcb.Parity = NOPARITY;			//无奇偶校验位 
	dcb.StopBits = ONESTOPBIT;		//一个停止位
	SetCommState(hCom, &dcb);		//设置参数到hCom
	PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR);//清空缓存区		//PURGE_TXABORT 中断所有写操作并立即返回，即使写操作还没有完成。
																	//PURGE_RXABORT 中断所有读操作并立即返回，即使读操作还没有完成。
																	//PURGE_TXCLEAR 清除输出缓冲区 
																	//PURGE_RXCLEAR 清除输入缓冲区  
	return TRUE;
}
int serial_read(char str[], int size)	//同步读串口
{

	DWORD rCount;	//读取的字节数
	BOOL bReadStat;
	bReadStat = ReadFile(hCom, str, size, &rCount, NULL);
	if (!bReadStat)
	{
		return FALSE;
	}
	return rCount;
}
int serial_write(char lpOutBuffer[], int size)	//同步写串口
{
	DWORD dwBytesWrite;
	COMSTAT ComStat;
	DWORD dwErrorFlags;
	BOOL bWriteStat;
	ClearCommError(hCom, &dwErrorFlags, &ComStat);
	bWriteStat = WriteFile(hCom, lpOutBuffer, size, &dwBytesWrite, NULL);
	if (!bWriteStat)
	{
		return FALSE;
	}
	PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
	return dwBytesWrite;
}

void Serial_close(void)		//关闭串口
{
	CloseHandle(hCom);
}

//以上为串口函数

int _tmain(int argc, _TCHAR* argv[])
{
	WSADATA wsd;
	SOCKET sServer;
	SOCKET sClient;
	SOCKADDR_IN servAddr;
	char buf[BUF_SIZE];
	int retVal;
	//声明程序所需的变量

	if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
	{
		printf("WSAStartup failed! \n");
		return 1;
	}
	//初始化Socket环境

	sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (INVALID_SOCKET == sServer)
	{
		printf("socket failed! \n");
		WSACleanup();
		return -1;
	}
	//创建server端的Socket

	SOCKADDR_IN addrServ;
	addrServ.sin_family = AF_INET;
	addrServ.sin_port = htons(9990);
	addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	//设置服务器监听地址为任意本地地址，设置端口号为9990

	retVal = bind(sServer, (const struct sockaddr*) & addrServ, sizeof(SOCKADDR_IN));
	if (retVal == SOCKET_ERROR)
	{
		printf("bind failed!\n");
		closesocket(sServer);
		WSACleanup();
		return -1;
	}
	//绑定SocketServer到本地地址

	retVal = listen(sServer, 1);
	if (SOCKET_ERROR == retVal)
	{
		printf("listen failed! \n");
		closesocket(sServer);
		WSACleanup();
		return -1;
	}
	//在ServerSocket上进行监听

	printf("TCP server socket start...\n");
	sockaddr_in addrClient;
	int addrClientlen = sizeof(addrClient);
	sClient = accept(sServer, (sockaddr FAR*) & addrClient, &addrClientlen);
	if (sClient == INVALID_SOCKET)
	{
		printf("accept error!\n ");
		closesocket(sServer);
		WSACleanup();
		return -1;
	}
	//接受客户端请求

	int j = 0;
	int i = 0;
	int len1, len2;
	char for_read[6];
	char going_write;
	printf("TCP server start successfully!\n");
	int state = serial_open(_T(comx), baud);
	if (state == 0)
	{
		retVal = send(sClient, "open COM false", strlen("open COM false"), 0);
		return -1;
	}
	while (true)
	{
		ZeroMemory(buf, BUF_SIZE);
		retVal = recv(sClient, buf, BUFSIZ, 0);
		going_write = buf[0];
		if (SOCKET_ERROR == retVal)
		{
			printf("recv failed! \n");
			closesocket(sServer);
			closesocket(sClient);
			WSACleanup();
			return -1;
		}
		if (strcmp(buf, "start") != 0 && j == 0)
		{
			char cls[BUF_SIZE] = "sensor has not worked yet!Please press 'start'!\n ";
			strcpy(buf, cls);
			retVal = send(sClient, buf, strlen(buf), 0);
			if (SOCKET_ERROR == retVal)
			{
				printf("send failed! \n");
				closesocket(sServer);
				closesocket(sClient);
				WSACleanup();
				return -1;
			}
			continue;
		}//sensor端启动命令检测
		if (strcmp(buf, "start") == 0 && j == 0)
		{
			for (i = 0; i < 10; i++)
			{
				len1 = serial_write(&going_write, 1);
				if (len1 != 0)
					break;
			}
			if (i == 10)
			{
				printf("写串口失败!\n");
				retVal = send(sClient, "write false", strlen("write false"), 0);
				return -1;
			}
			char sta[BUF_SIZE] = "sensor start!";
			printf("service start!");
			strcpy(buf, sta);
			retVal = send(sClient, buf, strlen(buf), 0);
			if (SOCKET_ERROR == retVal)
			{
				printf("send failed! \n");
				closesocket(sServer);
				closesocket(sClient);
				WSACleanup();
				return -1;
			}
			j++;
			continue;
		}//相应启动命令的输出信息

		if (strcmp(buf, "quit") == 0)
		{
			for (i = 0; i < 10; i++)
			{
				len1 = serial_write(&going_write, 1);
				if (len1 != 0)
					break;
			}
			if (i == 10)
			{
				printf("写串口失败!\n");
				retVal = send(sClient, "write false", strlen("write false"), 0);
				return -1;
			}
			retVal = send(sClient, "quit", strlen("quit"), 0);
			printf("Shutdown command recieved!");
			break;
		}//exit 
		/*int p, q, r;
		char msg[BUF_SIZE];
		memset(msg, 0, sizeof(msg));
		p = rand() % 2 + 3;
		if (p == 3)
		{
			q = rand() % 5 + 5;
		}
		else
		{
			q = rand() % 3 + 0;
		}
		r = rand() % 10 + 0;
		srand((unsigned)time(NULL));
		msg[0] = (char)'0' + p;
		msg[1] = (char)'0' + q;
		msg[2] = 46;
		msg[3] = (char)'0' + r;
		msg[4] = '\0';
		//生成随机数，范围35.0-42.0 */
		SYSTEMTIME st;
		GetLocalTime(&st);
		printf("%4d-%2d-%2d  %2d:%2d:%2d, Recv From Client [%s:%d]:%s\n",
			st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond,
			inet_ntoa(addrClient.sin_addr), addrClient.sin_port, "Temprature Sending Now");

		if (j >= 0)
		{   
			i = 0;
			if (strcmp(buf, "init") == 0 || strcmp(buf, "read") == 0)
			{
				for (i = 0; i < 10; i++)
				{
					len1 = serial_write(&going_write, 1);
					if (len1 != 0)
						if(going_write=='i')
							retVal = send(sClient, "init", strlen("init"), 0);
						break;
				}
				if (i == 10)
				{
					printf("写串口失败!\n");
					retVal = send(sClient, "write false", strlen("write false"), 0);
					return -1;
				}
				if (going_write == 'r')
				{
					Sleep(500);
					for (i = 0; i < 10; i++)
					{
						len2 = serial_read(for_read, 7);
						if (len2 != 0 && for_read[6] == '\0')
						{
							break;
						}
						/*else if (len2 == 0)
						{
							for (i = 0; i < 10; i++)
							{
								len1 = serial_write(&going_write, 1);
								if (len1 != 0)
								{
									Sleep(500);
									break;
								}
								if (i == 10)
								{
									printf("写串口失败!\n");
									retVal = send(sClient, "write false", strlen("write false"), 0);
									return -1;
								}
							}
						}*/
					}
					if (i == 10)
					{
						printf("读串口失败!\n");
						retVal = send(sClient, "read false", strlen("read false"), 0);
						return -1;
					}
					retVal = send(sClient, for_read, strlen(for_read), 0);
					if (SOCKET_ERROR == retVal)
					{
						printf("send failed! \n");
						closesocket(sServer);
						closesocket(sClient);
						WSACleanup();
						return -1;
					}
				}
			}
			/*retVal = send(sClient, msg, strlen(msg), 0);
			if (SOCKET_ERROR == retVal)
			{
				printf("send failed! \n");
				closesocket(sServer);
				closesocket(sClient);
				WSACleanup();
				return -1;
			}*/
			else
			{
				retVal = send(sClient, "command does not exist", strlen("command does not exist"), 0);
				if (SOCKET_ERROR == retVal)
				{
					printf("send failed! \n");
					closesocket(sServer);
					closesocket(sClient);
					WSACleanup();
					return -1;
				}
			}
			continue;
		}
	}
	//服务器与客户端传送信息

	closesocket(sServer);
	closesocket(sClient);
	WSACleanup();
	//释放空间
	system("pause");
	return 0;
}